
local NEWS_TEXT_KEY = "news_text"
local LAST_UPDATE_KEY = "last_update"

local mstore = minetest.get_mod_storage()

-- create formspec from string
local function get_formspec(text)

	local news_fs = 'size[12,8.25]'..
		"button_exit[-0.05,7.8;2,1;exit;Close]"
	if text and text ~= "" then
		news_fs = news_fs.."textarea[0.25,0;12.1,9;news;;"..minetest.formspec_escape(text).."]"
	else
		news_fs = news_fs.."textarea[0.25,0;12.1,9;news;;No current news.]"
	end
	return news_fs
end

-- If a news.txt exists, reads the contents and deletes the file. Returns file contents or nil if file does not exist.
local function take_new_news()
	local news_path = minetest.get_worldpath().."/news.txt"

	local news_file = io.open(news_path, "r")

	if news_file then
		local news = news_file:read("*a")
		news_file:close()
		os.remove(news_path)
		return news
	end
end

-- Ensure the news text in mod storage is current. Returns the text if an update has been made, otherwise nil.
local function maintain_news()
	local news = take_new_news()

	-- a new news file has been given
	if news then
		mstore:set_string(NEWS_TEXT_KEY, news)
		mstore:set_int(LAST_UPDATE_KEY, os.time());
		return news
	end

	return nil
end

local function get_cached_text()
	return mstore:get_string(NEWS_TEXT_KEY)
end

-- show news formspec on player join, unless they have already seen it
minetest.register_on_joinplayer(function (player, last_login)
	local text = maintain_news()

	if text -- updated text
		or not last_login -- first login
		or last_login <= mstore:get_int(LAST_UPDATE_KEY)
		-- not seen it yet (this will be incorrect if it's before 1970)
	then
		if not text then
			-- if it's not been updated, we need to get a cached copy
			text = get_cached_text()
		end

		if text then
			local name = player:get_player_name()
			minetest.show_formspec(name, "news", get_formspec(text))
		end
	end
end)

-- command to display server news at any time
minetest.register_chatcommand("news", {
	description = "Shows server news to the player",
	func = function (name)
		local player = minetest.get_player_by_name(name)
		minetest.show_formspec(name, "news", get_formspec(maintain_news() or get_cached_text()))
	end
})